package com.macaline.nio;

import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;

public class Demo {

    public static void main(String[] args) throws IOException, InterruptedException {
        b01();
    }

    @Test
    public void bo2() throws Exception {
        Selector selector = Selector.open();

        // 通道
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        // 非阻塞
        serverSocketChannel.configureBlocking(false);
        // 绑定连接
        serverSocketChannel.bind(new InetSocketAddress(9999));
        // 将通道注册到选择器上
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        // 选择器上keys
        Set<SelectionKey> selectededKeys = selector.selectedKeys();

        // 循环遍历key
        Iterator<SelectionKey> iterator = selectededKeys.iterator();
        while (iterator.hasNext()){
            SelectionKey key = iterator.next();

            if(key.isAcceptable()){
                System.out.println("isAcceptable----");
            }
            if(key.isConnectable()){
                System.out.println("isConnectable----");
            }
            if(key.isReadable()){
                System.out.println("isReadable----");
            }
            if(key.isWritable()){
                System.out.println("isWritable----");
            }

            // 去掉该key
//            iterator.remove();

        }

    }




    // 子缓冲区-分片
    public static void readOnlyBuffer(){
        IntBuffer buffer = IntBuffer.allocate(10);
        for (int i = 0; i < buffer.capacity(); i++) {
            buffer.put(i + 1);
        }

        // 创建自缓冲区
        buffer.position(3);
        buffer.limit(9);

        IntBuffer slice = buffer.slice();

        // 改变子缓冲区
        for (int i = 0; i < slice.capacity(); i++) {
            int val = slice.get(i);
            slice.put(i, val * 10);
        }

        // 还原设置
        buffer.position(0);
        buffer.limit(buffer.capacity());

        while (buffer.hasRemaining()){
            System.out.println(buffer.get());
        }
        buffer.clear();

    }



    // 子缓冲区-分片
    public static void b01(){
        IntBuffer buffer = IntBuffer.allocate(10);
        for (int i = 0; i < buffer.capacity(); i++) {
            buffer.put(i + 1);
        }

        // 创建自缓冲区
        buffer.position(3);
        buffer.limit(9);

        IntBuffer slice = buffer.slice();

        // 改变子缓冲区
        for (int i = 0; i < slice.capacity(); i++) {
            int val = slice.get(i);
            slice.put(i, val * 10);
        }

        // 还原设置
        buffer.position(0);
        buffer.limit(buffer.capacity());

        while (buffer.hasRemaining()){
            System.out.println(buffer.get());
        }
        buffer.clear();

    }


    // ServerSocketChannel
    public static void serverSocketChannel() throws IOException, InterruptedException {
        int port = 8888;

        // 绑定端口
        ServerSocketChannel socketChannel = ServerSocketChannel.open();
        socketChannel.socket().bind(new InetSocketAddress(port));
        // 设置不阻塞

        socketChannel.configureBlocking(false);
        ByteBuffer buffer = ByteBuffer.wrap("123".getBytes());

        while (true){
            SocketChannel accept = socketChannel.accept();
            if(accept == null){
                System.out.println("null");
                Thread.sleep(2000);
            }else {
                System.out.println("address:" + accept.socket().getRemoteSocketAddress());
                buffer.rewind();
                accept.write(buffer);
            }
        }
    }

    // File - transferFrom
    public void transferFrom() throws IOException {
        RandomAccessFile accessFile = new RandomAccessFile("D://0524.log", "rw");
        FileChannel toChannel = accessFile.getChannel();
        RandomAccessFile accessFile2 = new RandomAccessFile("D://0525.log", "rw");
        FileChannel fromChannel = accessFile2.getChannel();

        long size = toChannel.size();
        fromChannel.transferFrom(toChannel, 0, size);
        toChannel.close();
        fromChannel.close();
        System.out.println("over!");
    }


    // 写文件
    public void write() throws IOException {
        RandomAccessFile accessFile = new RandomAccessFile("D://0524.log", "rw");
        FileChannel channel = accessFile.getChannel();
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        buffer.clear();
        buffer.put("newData".getBytes());
        // 转换读写模式
        buffer.flip();
        while (buffer.hasRemaining()){
            channel.write(buffer);
        }
        channel.close();
    }

    // 读数据
    public void read() throws Exception {
        RandomAccessFile accessFile = new RandomAccessFile("D://0524.log", "rw");
        FileChannel channel = accessFile.getChannel();
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        int read = channel.read(buffer);
        while (read != -1){
            System.out.println(buffer.get());
            // 转换读写模式
            buffer.flip();
            while (buffer.hasRemaining()){
                System.out.println((char) buffer.get());
            }
            buffer.clear();
            read = channel.read(buffer);
        }
        channel.close();
    }

}
